Stop exporting winrt::impl::get_marshaler to workaround MSVC modules bug#1592
Stop exporting winrt::impl::get_marshaler to workaround MSVC modules bug#1592DefaultRyan wants to merge 1 commit into
Conversation
|
I think there is a certain issue with the current patch. Functions exported by C++/WinRT have extern "C++" {
#include "winrt/Windows.Foundation.h"
}Also, keep |
|
I don't think it's an ODR violation. The module's exported symbols will have module linkage, meaning they are not the same symbols. The only place we really need to use extern "C++" is when symbols need to be shared, like the winrt_get_activation_handler and other function pointer interfaces. |
|
No, |
|
Note the comment // In the STL's headers (which might be used to build the named module std), we unconditionally
// and directly mark declarations of our separately compiled machinery as extern "C++", allowing
// the named module to work with the separately compiled code (which is always built classically).
// TRANSITION: _USE_EXTERN_CXX_EVERYWHERE_FOR_STL controls whether we also wrap the STL's
// header-only code in this linkage-specification, as a temporary workaround to allow
// importing the named module in a translation unit with classic includes.This should not be a problem for us as we don't really support mixing includes and imports. We also do not have much in terms of separately built machinery. |
In my own fork, I have already implemented support for mixing includes and imports, and C++/WinRT has inherited this as well. |
TL;DRI'm not worried about ODR violations on Wall of textLinkage and By default, declarations in a module after
Any hope of adopting modules in real world projects will require headers and modules to coexist to some degree. There are many large projects already using C++/WinRT that will need to migrate incrementally. There are also external libraries and tools with widespread usage that assume C++/WinRT is in header form, or outright generate We can get MSVC to accept include-then-import by detaching these declarations from module ownership and module linkage by giving them language linkage instead, aka This, along with the separately compiled machinery, is what I believe to be the primary motivators for the STL to use language linkage by saying But The STL is not a code generator. It has a single set of headers and module interface files it ships, and has no interest in sharing its declarations with other modules. C++/WinRT, on the other hand, generates headers and module interfaces for whatever WinRT APIs it is fed, from multiple sources (SDK, Nuget/Project references, IDL/winmd) and so we need to allow for a certain amount of shared ownership. This was true before modules, which is part of why C++/WinRT has long had the version checks to ensure that the mixing and matching is compatible, via a combination of |
An MSVC bug was revealed where the combination of
export extern "C++", a function-local type in an inline function, and that type having a user-defined constructor, causes that constructed object to have a zero-filled vtable. So calling any virtual function causes a crash.This affected
winrt::impl::get_marshaler(), responsible for constructing the implementation ofIMarshalforwinrt::implements.Verified this bug by adding a case to
test_cpp20_modulethat constructs animplementsobject, and queries forIMarshal. The ensuing call toRelease()via that interface causes a crash.Since
winrt::impl::get_marshaler()is an implementation detail that doesn't need to be exported (and we are planning to reduce spurious exports anyway), it makes sense to stop exporting this function. This change is sufficient to workaround the MSVC bug and the test now passes.Fixes: #1590